序言

NVIDIA vGPU 是一种允许多个虚拟机使用受支持的单个物理 GPU 的技术。

NVIDIA 不允许在消费级 GPU 上使用 vGPU 功能,但是实际上硬件是完全支持的。

这里使用开源软件  vgpu_unlock  通过修补 NVIDIA 驱动的方式解锁了消费级 NVIDIA vGPU 功能。

当然这仅能使消费级 GPU 能够支持 vGPU 技术,而不是破解了授权。(所以还是需要去 NVIDIA 购买!)


基本要求

  • 一张 vgpu_unlock 支持的显卡(可以通过这个网站查询 DeivceID 与下面数据进行对比), 如果不使用 vgpu_unlock 仅需要满足支持 vGPU 即可
  • 开启 IOMMU
  • 开启 SR-IOV (部分显卡可能需要)

补充数据

vGPU unlock 支持的 GPU
Nvidia vGPU 显卡GPU 核心vGPU unlock 支持支持的显卡 DeviceID 范围
Tesla M10GM107 x4大多数 Maxwell 1.0 显卡[1340 , 13bd]∪[174d , 179c]
Tesla M60GM204 x2大多数 Maxwell 2.0 显卡[13c0 , 1436]∪[1617 , 1667]∪[17c2 , 17fd]
Tesla P40GP102大多数 Pascal 显卡[15f0 , 15f1]∪[1b00 , 1d56]∪[1725 , 172f]
Tesla V100 16GBGV100Titan V 和 Quadro GV100[1d81 , 1dba]
Quadro RTX 6000TU102大多数 Turing 显卡[1e02 , 1ff9]∪[2182 , 21d1]
RTX A6000GA102不支持 Ampere 显卡(有部分支持?)[2200 , 2600]
使用工具说明
工具说明
vgpu_unlock[1]修补驱动解锁限制 + 使用 frida hook ioctl
vgpu_unlock-rs[2]替换 vgpu_unlock 使用的 frida hook 方案
额外补丁 [3] [4]kernel >= 5.10-rc1 set_fs 函数被移除[5],从此版本开始需要额外打补丁 (仅限 4xx)
vgpu-proxmox[6]根据[7]制作的 patch 文件,简化 vgpu_unlock 操作
fastapi-dls[8]最小的 NVIDIA 授权服务器
vGPU-Unlock-patcher[9]一些补丁的自动化脚本 (没用过)
dkms用于动态安装内核模块,升降内核自动模块编译 (注意:需要安装 kernel-headers)
vGPU 不同类型比较

TIP

这不太重要,可以使用 vgpu_unlock-rs 自由调整

vGPU TypeOSUse CaseLicenseDisplayNotes
A-seriesWindows, LinuxVirtual ApplicationsvApps1280x1024, 1 displayGood for RDSH
B-seriesWindows, LinuxBasic PC workvPCUp to 5K, 2 displays45 FPS max
C-seriesLinuxCompute servervCSUp to 4K, 1 displayCUDA Only
Q-seriesWindows, LinuxProfessionalWorkstationvDWSUp to 8K, 4 displaysCUDA, OpenGL

安装驱动

环境准备

bash
apt install -y curl unzip git patch dkms mdevctl
apt install -y build-essential pve-headers-`uname -r`

驱动文件准备

下载名为 NVIDIA-Linux-x86_64-<version>-vgpu-kvm.run 驱动文件

安装

TIP

如果安装成功应该会显示这个输出。

Installation of the NVIDIA Accelerated Graphics Driver for Linux-x86_64 (version: <version>) is now complete.

kernel >= 5.10-rc1 and vGPU driver <= 4xx

INFO

从此版本开始 set_fs 函数被移除[5:1],所以需要额外打补丁

解包驱动

bash
chmod +x NVIDIA-Linux-x86_64-<version>-vgpu-kvm.run
./NVIDIA-Linux-x86_64-<version>-vgpu-kvm.run -x --target vgpu-kvm

打上额外补丁

bash
cd vgpu-kvm

# 补丁1:
curl -sSf https://raw.githubusercontent.com/rupansh/vgpu_unlock_5.12/master/twelve.patch | patch -p0
# 或者
# 补丁2:
curl -sSf https://gitlab.com/polloloco/vgpu-proxmox/-/raw/450-driver/450_5.15.patch | patch -p0

# 修改许可, 将 NVIDIA、Dual MIT/GPL、MIT 改为 GPL
# sed -i 's/^c("\(NVIDIA\|Dual MIT\/GPL\|MIT\)")/MODULE_LICENSE("GPL")/' ./kernel/nvidia/nv-frontend.c ./kernel/nvidia-vgpu-vfio/nvidia-vgpu-vfio.c

cd ..

安装

bash
./vgpu-kvm/nvidia-installer --dkms

显卡本身就支持 vGPU 可以不打解锁补丁直接安装

bash
./NVIDIA-Linux-x86_64-<version>-vgpu-kvm.run --dkms

应用解锁补丁 (可选)

补丁下载[6:1]: 选择对应的分支下载,文件名为 <version>.patch

修补

如果成功应该能看到 successfully created. 之类的文字

并在当前目录下会生产名称为 NVIDIA-Linux-x86_64-<version>-vgpu-kvm-custom.run 的文件

bash
chmod +x NVIDIA-Linux-x86_64-<version>-vgpu-kvm.run
./NVIDIA-Linux-x86_64-<version>-vgpu-kvm.run --apply-patch ./<version>.patch

安装

bash
./NVIDIA-Linux-x86_64-<version>-vgpu-kvm-custom.run --dkms

解包驱动

bash
chmod +x NVIDIA-Linux-x86_64-<version>-vgpu-kvm.run
./NVIDIA-Linux-x86_64-<version>-vgpu-kvm.run -x --target vgpu-kvm

打上解锁补丁 [10]

bash
git clone 'https://github.com/DualCoder/vgpu_unlock.git' vgpu_unlock

cp -l vgpu_unlock/kern.ld vgpu-kvm/kernel/nvidia/kern.ld
cp -l vgpu_unlock/vgpu_unlock_hooks.c vgpu-kvm/kernel/common/inc/vgpu_unlock_hooks.c

# 在文件 vgpu-kvm/kernel/nvidia/nvidia.Kbuild 的末尾插入 ldflags-y += -T $(src)/nvidia/kern.ld
sed -i '$ a ldflags-y += -T $(src)/nvidia/kern.ld' vgpu-kvm/kernel/nvidia/nvidia.Kbuild
# 在文件 vgpu-kvm/kernel/nvidia/os-interface.c 的32行后插入 #include "vgpu_unlock_hooks.c"
sed -i '32 a #include "vgpu_unlock_hooks.c"' vgpu-kvm/kernel/nvidia/os-interface.c

echo 'kernel/nvidia/kern.ld 0644 KERNEL_MODULE_SRC INHERIT_PATH_DEPTH:1 MODULE:resman' >> vgpu-kvm/.manifest
echo 'kernel/common/inc/vgpu_unlock_hooks.c 0644 KERNEL_MODULE_SRC INHERIT_PATH_DEPTH:1 MODULE:vgpu' >> vgpu-kvm/.manifest

安装

bash
./vgpu-kvm/nvidia-installer --dkms

安装 vgpu_unlock-rs (可选)

安装环境

bash
# 国内请使用镜像安装 见: https://rsproxy.cn/

curl https://sh.rustup.rs -sSf | sh -s -- -y --profile minimal
source $HOME/.cargo/env
# 版本过老
#apt -y install cargo rustc

编译

bash
git clone https://github.com/mbilker/vgpu_unlock-rs vgpu_unlock-rs
cd vgpu_unlock-rs

# 编译过程需要下载文件,可能会失败
cargo build --release

cd ..

安装

bash
cp vgpu_unlock-rs/target/release/libvgpu_unlock_rs.so /lib/nvidia/libvgpu_unlock_rs.so

mkdir /etc/systemd/system/{nvidia-vgpud.service.d,nvidia-vgpu-mgr.service.d}
echo '[Service]
Environment=LD_PRELOAD=/lib/nvidia/libvgpu_unlock_rs.so' | tee /etc/systemd/system/nvidia-{vgpu-mgr,vgpud}.service.d/vgpu_unlock-rs.conf

systemctl daemon-reload
systemctl enable nvidia-{vgpu-mgr,vgpud}.service

配置

创建空的配置文件

bash
mkdir /etc/vgpu_unlock
touch /etc/vgpu_unlock/profile_override.toml

配置文件说明,可能有误具体看源码

toml
unlock = 1 # 启用解锁功能(不需要unlock vGPU可以设置为0)
# unlock_migration = 1 # 解锁 VM 迁移功能

# 这里的nvidia-<n>通过 mdevctl types 命令查询得到
# 工作模式为覆盖,所以nvidia-<n>是必须存在的mdev设备
# 更多设置请查看源码 https://github.com/mbilker/vgpu_unlock-rs/blob/master/src/lib.rs#L235-L264
[profile.nvidia-<n>]
num_displays = 1          # 虚拟显示器的最大数量
display_width = 1920      # 最大显示宽度
display_height = 1080     # 最大显示高度
max_pixels = 2073600      # 最大像素 max_pixels=display_width*display_height
cuda_enabled = 1          # 是否开启CUDA
frl_enabled = 1           # 如果开启会限制帧率为60fps
framebuffer = 0x76000000  # VRAM的大小
                          # 其他选项:
                          # 1GB: 0x3B000000
                          # 2GB: 0x76000000
                          # 3GB: 0xB1000000
                          # 4GB: 0xEC000000
                          # 8GB: 0x1D8000000
                          # 16GB: 0x3B0000000
                          # 这些数据仅供参考,你可以通过此方法计算
                          # VRAM=`framebuffer`+`framebuffer_reservation`
# 修改did和sdis,svid
# 似乎只对Windows有效
# 你可以通过这个网站用Ctrl+F查询相同核心显卡的DeivceID(设备ID)
# https://devicehunt.com/view/type/pci/vendor/10DE/
# pci_device_id = 0x1E30    # 0x<did> 由设备ID组成
# pci_id = 0x1E3012BA       # 0x<sdid><svid> 由子设备ID和子供应商ID组成

# 使用 mdevctl list 查看已经创建的 mdev
[mdev.<00000000-0000-0000-0000-000000000000>]
# 具体配置同上

# 仅pve支持
[vm.<VMID>]
# 具体配置同上

屏蔽 NVIDIA GPU 开源驱动

Proxmox 自带了适用于 NVIDIA GPU 的开源驱动程序,所以我们要屏蔽掉它然后使用 vGPU 驱动。

bash
echo "blacklist nouveau" >> /etc/modprobe.d/blacklist.conf
# 似乎可以不执行
update-initramfs -u -k all

重启主机

bash
reboot

验证安装

检查驱动是否安装成功

bash
nvidia-smi

输出类似如下

shell
+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 535.54.06              Driver Version: 535.54.06    CUDA Version: N/A      |
|-----------------------------------------+----------------------+----------------------+
| GPU  Name                 Persistence-M | Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap |         Memory-Usage | GPU-Util  Compute M. |
|                                         |                      |               MIG M. |
|=========================================+======================+======================|
|   0  Tesla P40                      On  | 00000000:05:00.0 Off |                    0 |
| N/A   38C    P8              19W / 250W |   7668MiB / 23040MiB |      1%      Default |
|                                         |                      |                  N/A |
+-----------------------------------------+----------------------+----------------------+

+---------------------------------------------------------------------------------------+
| Processes:                                                                            |
|  GPU   GI   CI        PID   Type   Process name                            GPU Memory |
|        ID   ID                                                             Usage      |
|=======================================================================================|
|   No running processes found                                                          |
+---------------------------------------------------------------------------------------+

检查 vGPU 是否解锁成功

bash
mdevctl types

输出类似如下,如果没有输出说明解锁失败

shell
0000:05:00.0
  nvidia-156
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-2B
    Description: num_heads=4, frl_config=45, framebuffer=2048M, max_resolution=5120x2880, max_instance=12
  nvidia-215
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-2B4
    Description: num_heads=4, frl_config=45, framebuffer=2048M, max_resolution=5120x2880, max_instance=12
  nvidia-241
    Available instances: 0
    Device API: vfio-pci
    Name: GRID P40-1B4
    Description: num_heads=4, frl_config=45, framebuffer=1024M, max_resolution=5120x2880, max_instance=24
---SNIP---

检查此卡是否被识别为启用了 vGPU

bash
nvidia-smi vgpu

如果输出 No supported devices in vGPU mode ,请检查以上步骤是否出现错误。

如果检查无误,说明此卡不支持 vGPU。

错误排查

你需要有一定的 Linux 知识和看懂报错的能力,这些命令或许对你有帮助

bash
dmesg
journalctl --no-pager -b 0 -u nvidia-vgpud
journalctl --no-pager -b 0 -u nvidia-vgpu-mgr
uname -a
cat /proc/cmdline

在 Proxmox 虚拟机中使用 vGPU

qemu-server < 7.2-4
bash
apt list nvidia-smi

修改 /etc/pve/qemu-server/<VMID>.conf 文件

shell
# /etc/pve/qemu-server/<VMID>.conf
# 在首行追加新的一行,第5段一共12位,不足位前面补0
args: -uuid 00000000-0000-0000-0000-00000000<VMID>  // [!code ++]

打开 Proxmox Web 界面,转到对应的 VM,添加一个 PCI 直通设备。选择对应 GPU 和对应 MDev Type 并添加。

Proxmox vGPU 配置

下载链接

工具

vgpu_unlock

vgpu_unlock-rs

vgpu-proxmox

fastapi-dls

vGPU 驱动

APQA 网盘 – vGPU (有最新版)

适用于 NVIDIA RTX 虚拟工作站的驱动程序 (仅包含 guest 驱动)

NVIDIA-VGPU-Driver-Archive (推荐使用 删库了)

NVIDIA-VGPU-Driver-Archive (archive.org 还有一部分)

之前备份了整个 NVIDIA-VGPU-Driver-Archive, 不过为了方便存储是解包过的,只保留有完整的压缩包结构

NVIDIA-VGPU-Driver-Archive (IPFS 建议用客户端)

相关教程

vGPU 教程 – 国光的 PVE 环境搭建教程

在 Proxmox VE 7.2 中开启 vGPU_unlock,实现显卡虚拟化

vGPU 在 Proxmox VE 下的配置与使用

Proxmox VE Nvidia-vGPU doc

安装 NVIDIA Virtual GPU Manager

补充说明

  • nvidia-smi vgpu 查询出的可能不是覆盖后的信息,可以参考这个创建一个启动文件
  • 虚拟机中的驱动版本不能高于宿主机
  • 文章可能有误,这只是一个笔记。

脚注


  1. vgpu_unlock ↩︎

  2. vgpu_unlock-rs ↩︎

  3. 修补文件 1 ↩︎

  4. 修补文件 2 ↩︎

  5. set_fs remove ↩︎ ↩︎

  6. vgpu-proxmox ↩︎ ↩︎

  7. vgpu 文档 ↩︎

  8. fastapi-dls ↩︎

  9. vGPU-Unlock-patcher ↩︎

  10. patch vgpu_unlock ↩︎